/**
 * Created by xinxinran on 2017/1/3.
 */
'use strict';

let appContext;
const baseClass = require('../socket/baseClass'),
    commonUtil = require('./commonUtil');

//noinspection JSUnusedGlobalSymbols
commonUtil.extendObj(exports, {
    initContext : function(context){
        appContext = context;
    },
    getBean : function(beanName, ver){
        return appContext.getBean(ver ? beanName + '_v' + ver : beanName);
    },
    getServiceNameWithVer : function(n, m){
        const fp = m.filename;
        let ver = /^\/?(?:(?:[^/]+\/)+)([^/]+)\/[^/]+$/.exec(fp.replace(/\\/g, '/'));

        ver = ver && ('_' + ver[1]);

        return n + (ver || '');
    },
    makeBeanDefineObj : function(func, m, extAttributes){
        let tmpInitObj, defObj, beanId, props;
        const injectExpr = /^\$(v?)->(.*)$/;
        let injectInfo;
        const _this = this;
        if(func.isSubClassOf && func.isSubClassOf(baseClass.BaseComponent)){
            tmpInitObj = new func();
            beanId = tmpInitObj.id;
            props = [];
            commonUtil.each(tmpInitObj, function(prop, v){
                if(tmpInitObj.hasOwnProperty(prop) && typeof v === 'string'){
                    injectInfo = injectExpr.exec(v);
                    injectInfo && props.push({
                        name : prop,
                        ref : injectInfo[1] ? _this.getServiceNameWithVer(injectInfo[2], m) : injectInfo[2]
                    })
                }
            });

            defObj = {
                func : func
            };
            defObj.id = m ? this.getServiceNameWithVer(beanId, m) : beanId;
            defObj.props = props;

            func.__beanName = defObj.id;

            commonUtil.each(extAttributes || [], function(_, attrName){
                defObj[attrName] = func[attrName];
            });
            return defObj;
        }

        return func;
    },
    getContextBeanByConstructor : function(func){
        if(!func){
            return null;
        }

        if(typeof func !== 'function'){
            func = func.constructor;
        }

        return func.__beanName && appContext.getBean(func.__beanName);
    },
    getDaoRelateModalName : function(daoBean, func){
        let content, modalInfo, propName, modalName;
        const cacheProperty = '__rModalName';
        if(!func){
            return null;
        }

        if(func[cacheProperty] !== void(0)){
            return func[cacheProperty];
        }

        content = func.toString();
        modalInfo = /\.getModel\s*\(\s*[a-zA-Z0-9_$]+\s*,\s*(?:(?:this(?:(?:\.([a-zA-Z0-9_$]+))|(?:\[(['"])([a-zA-Z0-9_$]+)\2])))|((['"])([a-zA-Z0-9_$]+)\5))\s*\)/.exec(content);
        if(modalInfo){
            propName = modalInfo[1] || modalInfo[3];
            if(propName){
                modalName = daoBean[propName];
            }else{
                modalName = modalInfo[6];
            }
            func[cacheProperty] = modalName;
            return modalName;
        }

        return func[cacheProperty] = null;
    }
}) ;
